#include "Qik.h"
#include "Matrix.h"
#include "ByteStream.h"
#include "DoubleMatrix.h"
#include "getopt.h"
#include "RunLengthEncoder.h"
#include "RunLengthDecoder.h"
#include "QikMovie.h"

int main (int argc, char **argv)
{
	int c;
	int cflg = 0;
	int dflg = 0;
	int errflg = 0;
	char *ofile = 0;
	char *ifile = 0;
	float defaultScale = 0;
	float scale = defaultScale;
	unsigned int gopsize = 3;
	unsigned int windowsize = 2*16;

	unsigned int width = 0, height = 0;
	bool motionCompensation = true;


	while ((c = getopt(argc, argv, "mcdi:o:f:s:l:g:w:")) != EOF)
	{
		switch (c) 
		{
		case 'm':
			motionCompensation = false;
			break;
		case 'g':
			sscanf(optarg, "%d", &gopsize);
			if (gopsize < 1)
			{
				printf("Warning: gopsize cannot be smaller than 1\n");
				gopsize = 1;
			}
			break;
		case 'w':
			sscanf(optarg, "%d", &windowsize);
			if (windowsize < 18)
			{
				printf("Warning: windowsize cannot be smaller than 18\n");
				windowsize = 18;
			}
			break;
		case 'f':
			sscanf(optarg, "%f", &scale);
			if (scale < 0)
			{
				printf("Warning: scale cannot be smaller than 0\n");
				scale = 0;
			}
			break;
		case 's':
			width = 0;
			height = 0;
			sscanf(optarg, "%dx%d", &width, &height);
			break;

		case 'c':
			if (dflg)
				errflg = 1;
			else
				cflg = 1;
			break;

		case 'd':
			if (cflg)
				errflg = 1;
			else
				dflg = 1;
			break;

		case 'o':
			ofile = optarg;
			break;

		case 'i':
			ifile = optarg;
			break;

		case '?':
		default:
			errflg = 1;
		}
	}
	for (; optind < argc; optind++)
	{
		fprintf(stderr, "Unknown option: %s\n", argv[optind]);
		errflg = 1;
	}

	if (!cflg && !dflg)
		errflg = 1;

	if (!ifile)
		errflg = 1;

	if (!ofile)
		errflg = 1;


	if (errflg) 
	{
		fprintf(stderr, "usage: %s [-c|-d] [-i <in-filename>] [-o <out-filename>] {-f <scalefactor>} {-s <widthxheight>} {-g <gopsize>} {-w <windowsize>} {-m}\n", argv[0]);
		fprintf(stderr, "\t-m: disable motion compensation\n");
		exit(-1);
	}

	try
	{
		QikMovie qikmovie;


		if (cflg)
		{
			if (width == 0 || height == 0)
			{
				fprintf(stderr, "Error: need image size (got %dx%d)\n", width, height);
				errflg = 1;
			}

			qikmovie.SetDimension(width, height);
			qikmovie.SetCompressionFactor(scale);
			qikmovie.SetGopSize(gopsize);
			qikmovie.SetWindowSize(windowsize);



			// Compress:
			qikmovie.ReadRawFromFile(ifile);
			qikmovie.WriteToFile(ofile);


		}
		else if (dflg)
		{
			if (scale != defaultScale)
				printf("Warning: ignoring scale parameter for decompressing\n");

			// Decompress:
			if (!motionCompensation)
				qikmovie.DisableMotionCompensation();

			qikmovie.ReadFromFile(ifile);
			qikmovie.WriteRawToFile(ofile);
		}
	}
	catch(char *s)
	{
		printf("Error: %s\n", s);
	}
	catch(...)
	{
		printf("Error\n");
	}

	return 0;
}

